package org.study.springboot.exception.handler.model;

import lombok.Data;
import org.study.springboot.exception.handler.constant.Status;
import org.study.springboot.exception.handler.exception.BaseException;

/**
 * <p>
 * 通用的API接口封装
 * </p>
 *
 * @author fangyu
 * @version v1.0.0
 * @date 2020/11/18 11:08 上午
 */
@Data
public class APIResponse {
    /**
     * 状态码
     */
    private Integer code;

    /**
     * 返回内容
     */
    private String message;

    /**
     * 返回数据
     */
    private Object data;

    /**
     * 无参构造函数
     */
    private APIResponse() {

    }

    /**
     * 全参构造函数
     *
     * @param code    状态码
     * @param message 返回内容
     * @param data    返回数据
     */
    public APIResponse(Integer code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    /**
     * 构造一个自定义的API返回
     *
     * @param code    状态码
     * @param message 返回内容
     * @param data    返回数据
     * @return APIResponse
     */
    public static APIResponse of(Integer code, String message, Object data) {
        return new APIResponse(code, message, data);
    }


    /**
     * 构建一个成功且带数据的API返回
     * @param data   返回数据
     * @return APIResponse
     */
    public static APIResponse ofSuccess(Object data) {
        return ofStatus(Status.OK, data);
    }

    /**
     * 构建一个成功自定义消息的API返回
     * @param message 自定义返回消息
     * @return APIResponse
     */
    public static APIResponse ofMessage(String message) {
        return of(Status.OK.getCode(), message, null);
    }

    /**
     * 构建一个有状态的API返回
     * @param status 状态 {@link Status}
     * @return APIResponse
     */
    public static APIResponse ofStatus(Status status) {
        return ofStatus(status, null);
    }

    /**
     * 构建一个有状态且带数据的API返回
     * @param status 状态 {@link Status}
     * @param data   返回数据
     * @return APIResponse
     */
    public static APIResponse ofStatus(Status status, Object data) {
        return of(status.getCode(), status.getMessage(), data);
    }

    /**
     * 构建一个异常且带数据的API返回
     * @param t     异常
     * @param <T>   {@link BaseException}
     * @param data  返回数据
     * @return APIResponse
     */
    public static <T extends BaseException> APIResponse ofException(T t, Object data) {
        return of(t.getCode(), t.getMessage(), data);
    }

    /**
     * 构建一个异常数据为空的API返回
     * @param t     异常
     * @param <T>   {@link BaseException}
     * @return APIResponse
     */
    public static <T extends BaseException> APIResponse ofException(T t) {
        return ofException(t, null);
    }
}
